home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 1452 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.0 KB  |  116 lines

  1. Path: mail2news.demon.co.uk!genesis.demon.co.uk
  2. From: Lawrence Kirby <fred@genesis.demon.co.uk>
  3. Newsgroups: comp.lang.c
  4. Subject: Re: my atoi function, could someone suggest...
  5. Date: Sat, 13 Jan 96 22:45:57 GMT
  6. Organization: none
  7. Message-ID: <821573157snz@genesis.demon.co.uk>
  8. References: <4cf7ap$q4u@kaleka.seanet.com> <4cq937$if9@ns.RezoNet.NET> <4d6v51$qoh@gryphon.phoenix.net>
  9. Reply-To: fred@genesis.demon.co.uk
  10. X-NNTP-Posting-Host: genesis.demon.co.uk
  11. X-Newsreader: Demon Internet Simple News v1.27
  12. X-Mail2News-Path: genesis.demon.co.uk
  13.  
  14. In article <4d6v51$qoh@gryphon.phoenix.net>
  15.            brucew@phoenix.net "Bruce Wedding" writes:
  16.  
  17. >ray@ultimate-tech.com (Ray Dunn) wrote:
  18. >
  19. >How about this version:
  20. >
  21. >int atoi(char *s)
  22.  
  23. The standard atoi function takes an argument of type const char *. It is
  24. sensible for a user function to do the same when it doesn't modify what
  25. is being pointed at.
  26.  
  27. >{
  28. >        int i, n, sign;
  29. >        
  30. >        for ( i = 0; s[i] == ' ' || s[i] == '\n' || s[i] == '\t'; i++);
  31. >                /* skip white space */
  32.  
  33. The standard atoi is defined in terms of leading white-space as defined
  34. by isspace(). Therefore it is probably more correct (as well as possibly
  35. more efficient) to use this.
  36.  
  37. As a matter of style I suggest you avoid terminating a for statement with
  38. a ; on the same line as the for itself - this is too easy to overlook.
  39.  
  40. >        sign = 1;
  41. >        if ( s[i] == '+' || s[i] == '-')
  42. >                sign = (s[i++] == '+') ? 1 : -1;
  43.  
  44. This could probably be simplified.
  45.  
  46. >        for (n = 0; s[i] >= '0' && s[i] <= '9'; i++)
  47. >                n = 10 * n + s[i] - '0';
  48. >        return(sign * n);
  49.  
  50. This could have problems with INT_MIN whose magnitude can be greater than
  51. INT_MAX.
  52.  
  53. >}
  54.  
  55. I give the following as an example of some alternative approaches.
  56. Ray's code in particular is good, and some may prefer it.
  57.  
  58. #include <ctype.h>
  59.  
  60. int myatoi(const char *str)
  61.  
  62. {
  63.     int     negative;
  64.  
  65.     while (isspace(*str))
  66.         str++;
  67.  
  68.     switch (*str) {
  69.     case '-':
  70.         str++;
  71.         negative = 1;
  72.         break;
  73.     case '+':
  74.         str++;
  75.         /* Continues */
  76.     default:
  77.         negative = 0;
  78.         break;
  79.     }
  80.  
  81.     {
  82.         unsigned value = 0;
  83.         unsigned digit = *str - '0';
  84.  
  85.         if (digit < 10) {
  86.             value = digit;
  87.  
  88.             while ((digit = *++str - '0') < 10)
  89.                 value = value * 10 + digit;
  90.         }
  91.  
  92.         return (negative && value != 0) ? -(int)(value-1)-1 : (int)value;
  93.     }
  94. }
  95.  
  96. The assumptions here are that the magnitude of INT_MIN is no larger than
  97. UINT_MAX and also no larger than INT_MAX+1.
  98.  
  99. It is interesting to note in passing that on my particular system the return
  100. expression compiles to simply:
  101.  
  102.     testl   %esi,%esi
  103.     je      .L17
  104.     testl   %eax,%eax
  105.     je      .L17
  106.     negl    %eax
  107. .L17
  108.  
  109. so it isn't as bad as it first looks! :-)
  110.  
  111. -- 
  112. -----------------------------------------
  113. Lawrence Kirby | fred@genesis.demon.co.uk
  114. Wilts, England | 70734.126@compuserve.com
  115. -----------------------------------------
  116.